//@version=5
indicator("Heikin-Ashi-Candles — change BUY/SELL colors (HTF proof)", overlay=true, max_boxes_count=250, max_lines_count=500)

get_stop_loss(bool is_confirmed, float low_, float high_, int length=2) =>
    sl_low = ta.lowest(low_, length)
    sl_high = ta.highest(high_, length)
    if not is_confirmed
        sl_low := ta.lowest(low_, length + 1)
        sl_high := ta.highest(high_, length + 1)
    [sl_low, sl_high]
    
// --- Inputs ---
tf              = input.timeframe('', title='Time-Frame')
trans           = input.int(30, title='Transparency Body (confirmed)', minval=0, maxval=100)
unfinishedT     = input.int(30, title='Transparency Body (unfinished)', minval=0, maxval=100)
wickW           = input.int(4,  title='Wick Width', minval=1, maxval=10)
borderWidthFin  = input.int(2,  title='Border Width (confirmed)', minval=1, maxval=5)
borderWidthUnf  = input.int(2,  title='Border Width (unfinished)', minval=1, maxval=10)
bullColorInput  = input.color(color.new(color.teal, 0), title='Bullish Color')
bearColorInput  = input.color(color.new(color.red,   0), title='Bearish Color')

// NEU: Farben für Change-Kerzen (Buy/Sell getrennt)
changeBuyColor  = input.color(color.new(color.white, 0), title='Change Color (Buy)')
changeSellColor = input.color(color.new(color.yellow, 0), title='Change Color (Sell)')

// --- HA-Daten laden (HTF) ---
[ha_open, ha_high, ha_low, ha_close, ha_time, ha_bar_index] = request.security(ticker.heikinashi(syminfo.tickerid), tf, [open, high, low, close, time, bar_index], lookahead=barmerge.lookahead_off)

// Live-Richtung der *laufenden* HTF-HA-Kerze (kann intrabar kippen)
dir_live = ha_close > ha_open ? 1 : -1

// Richtungen der *bestätigten* HTF-HA-Kerzen
f_last_conf_dir() =>
    d = close > open ? 1 : -1
    ta.valuewhen(barstate.isconfirmed, d, 0)

f_prev_conf_dir() =>
    d = close > open ? 1 : -1
    ta.valuewhen(barstate.isconfirmed, d, 1)

dir_conf_last = request.security(ticker.heikinashi(syminfo.tickerid), tf, f_last_conf_dir(), lookahead=barmerge.lookahead_off)
dir_conf_prev = request.security(ticker.heikinashi(syminfo.tickerid), tf, f_prev_conf_dir(), lookahead=barmerge.lookahead_off)

// Start einer neuen HTF-HA-Kerze
newHA = ta.change(ha_time)

// Persistenter Flag: wird innerhalb des Bars gesetzt, sobald Live-Richtung ≠ letzte bestätigte Richtung
var bool currIsChange = false
if newHA
    currIsChange := false
if not na(dir_conf_last) and dir_live != dir_conf_last
    currIsChange := true

// War die soeben geschlossene (letzte bestätigte) Kerze selbst ein Richtungswechsel?
closed_changed = not na(dir_conf_last) and not na(dir_conf_prev) and dir_conf_last != dir_conf_prev

// --- Bestätigung/unfinished im HTF ---
ha_confirmed = request.security(ticker.heikinashi(syminfo.tickerid), tf, barstate.isconfirmed, lookahead=barmerge.lookahead_off)
unfinished   = not ha_confirmed

// --- Farben & Transparenzen (Basis) ---
isBull            = ha_close >= ha_open
borderT           = math.max(0, math.min(100, trans - 10))
unfinishedBorderT = math.max(0, math.min(100, unfinishedT - 10))

baseColor       = isBull ? bullColorInput : bearColorInput
bodyColor_unf   = color.new(baseColor, unfinishedT)
borderCol_unf   = color.new(color.white, unfinishedBorderT)  // weißer Rahmen für unbestätigte Candle
bodyColor_fin   = color.new(baseColor, trans)
borderCol_fin   = color.new(baseColor, borderT)

// Wick-Farbe: unbestätigt weiß, sonst Body-Farbe
wickColor_base = unfinished ? color.new(color.white, unfinishedBorderT) : bodyColor_fin

// Aktuelle Darstellungsfarben (werden ggf. durch Change-Farben ersetzt)
bodyColor   = unfinished ? bodyColor_unf : bodyColor_fin
borderCol   = unfinished ? borderCol_unf : borderCol_fin
wickColor   = wickColor_base
borderWidth = unfinished ? borderWidthUnf : borderWidthFin

// --- Wenn die *aktuelle* HTF-Kerze ein Change ist → ALLES in konfigurierter Buy/Sell-Farbe ---
if currIsChange
    chCol = dir_live == 1 ? changeBuyColor : changeSellColor
    bodyColor := chCol
    borderCol := chCol
    wickColor := chCol

// --- persistente Referenzen ---
var box  bodyBox   = na
var line wickUpper = na
var line wickLower = na
var int  leftX     = na

// Hilfswerte für Body/Wicks
bodyTop    = math.max(ha_open, ha_close)
bodyBottom = math.min(ha_open, ha_close)

// --- die soeben geschlossene HTF-HA-Kerze final einfärben ---
if newHA and not na(bodyBox)
    // Standard-Finalfarben (falls kein Change)
    prev_isBull   = ha_close[1] >= ha_open[1]
    prev_base     = prev_isBull ? bullColorInput : bearColorInput
    prev_body_fin = color.new(prev_base, trans)
    prev_border   = color.new(prev_base, math.max(0, math.min(100, trans - 10)))
    prev_wick_fin = prev_body_fin

    // Falls die geschlossene Kerze ein Change-Bar war → mit konfigurierter Buy/Sell-Farbe finalisieren
    prevChangeCol = dir_conf_last == 1 ? changeBuyColor : changeSellColor
    final_body    = closed_changed ? prevChangeCol : prev_body_fin
    final_border  = closed_changed ? prevChangeCol : prev_border
    final_wick    = closed_changed ? prevChangeCol : prev_wick_fin

    box.set_bgcolor(bodyBox, final_body)
    box.set_border_color(bodyBox, final_border)
    box.set_border_width(bodyBox, borderWidthFin)
    line.set_color(wickUpper, final_wick)
    line.set_color(wickLower, final_wick)

// --- neue Candle anlegen ---
if newHA
    leftX     := bar_index
    bodyBox   := box.new(leftX, bodyTop, bar_index, bodyBottom, bgcolor=bodyColor, border_color=borderCol, border_width=borderWidth)
    wickUpper := line.new(leftX, bodyTop, leftX, ha_high, color=wickColor, width=wickW)
    wickLower := line.new(leftX, bodyBottom, leftX, ha_low,  color=wickColor, width=wickW)

// --- laufende Candle aktualisieren ---
if not na(bodyBox)
    box.set_right(bodyBox, bar_index)
    box.set_top(bodyBox, bodyTop)
    box.set_bottom(bodyBox, bodyBottom)
    box.set_bgcolor(bodyBox, bodyColor)
    box.set_border_color(bodyBox, borderCol)
    box.set_border_width(bodyBox, borderWidth)

// Wicks mittig platzieren
midX = na(leftX) ? bar_index : int(math.round((leftX + bar_index) / 2.0))

if not na(wickUpper)
    line.set_x1(wickUpper, midX)
    line.set_x2(wickUpper, midX)
    line.set_y1(wickUpper, bodyTop)
    line.set_y2(wickUpper, ha_high)
    line.set_color(wickUpper, wickColor)
    line.set_width(wickUpper, wickW)

if not na(wickLower)
    line.set_x1(wickLower, midX)
    line.set_x2(wickLower, midX)
    line.set_y1(wickLower, bodyBottom)
    line.set_y2(wickLower, ha_low)
    line.set_color(wickLower, wickColor)
    line.set_width(wickLower, wickW)

crv = input.float(1.3, title='Risk-Reward-Ratio', group='Trading')
sl_lenght = input.int(2, title='Stop-Loss Length', minval=1, maxval=100, group='Trading')
trans_t = input.int(75, title='Transparency Trading', minval=0, maxval=100, group='Trading')



[sl_low, sl_high] = request.security(ticker.heikinashi(syminfo.tickerid), tf, get_stop_loss(barstate.isconfirmed, high_ = ha_high[1], low_=ha_low[1], length = sl_lenght), lookahead = barmerge.lookahead_off)
price = request.security(ticker.standard(syminfo.tickerid), '', close, lookahead = barmerge.lookahead_off)

sl = isBull ? sl_low : sl_high
tp = isBull ? price + math.abs(price - sl_low) * crv : price - math.abs(price - sl_high) * crv

plot_sl = plot(sl, 'Stop-Loss', color = color.new(color.red, trans_t))
plot_tp = plot(tp, 'Take-Profit', color = color.new(color.teal, trans_t))
plot_price = plot(price, 'Entry Price', color = color.new(color.gray, trans_t))

fill(plot_sl, plot_price, color = color.new(color.red, trans_t), fillgaps = true)
fill(plot_tp, plot_price, color = color.new(color.teal, trans_t), fillgaps = true)


if closed_changed and dir_conf_last == 1 and ha_bar_index != ha_bar_index[1]
    alert(message = 'BUY - Heikin-Ashi-Candles MTF', freq = alert.freq_once_per_bar)

if closed_changed and dir_conf_last == -1 and ha_bar_index != ha_bar_index[1]
    alert(message = 'SELL - Heikin-Ashi-Candles MTF', freq = alert.freq_once_per_bar)

